---
title: Prefetch
description: Prefetch links for snappier navigation between pages.
i18nReady: true
---

import { Steps } from '@astrojs/starlight/components'
import Since from '~/components/Since.astro'

Page load times play a big role in the usability and overall enjoyment of a site. Astro's **opt-in prefetching** brings the benefits of near-instant page navigations to your multi-page application (MPA) as your visitors interact with the site.

## Enable prefetching

You can enable prefetching with the `prefetch` config:

```js title="astro.config.mjs" ins={4}
import { defineConfig } from 'astro/config';

export default defineConfig({
  prefetch: true
});
```

A prefetch script will be added to all pages of your site. You can then add the `data-astro-prefetch` attribute to any `<a />` links on your site to opt-in to prefetching. When you hover over the link, the script will fetch the page in the background.

```html
<a href="/about" data-astro-prefetch>
```

Note that prefetching only works for links within your site, and not external links.

## Prefetch configuration

The `prefetch` config also accepts an option object to further customize prefetching.

### Prefetch strategies

Astro supports 4 prefetch strategies for various use cases:

- `hover` (default): Prefetch when you hover over or focus on the link.
- `tap`: Prefetch just before you click on the link.
- `viewport`: Prefetch as the links enter the viewport.
- `load`: Prefetch all links on the page after the page is loaded.

You can specify a strategy for an individual link by passing it to the `data-astro-prefetch` attribute:

```html
<a href="/about" data-astro-prefetch="tap">About</a>
```

Each strategy is fine-tuned to only prefetch when needed and save your users' bandwidth. For example:

- If a visitor is using [data saver mode](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/saveData) or has a [slow connection](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType), prefetch will fallback to the `tap` strategy.
- Quickly hovering or scrolling over links will not prefetch them.

### Default prefetch strategy

The default prefetch strategy when adding the `data-astro-prefetch` attribute is `hover`. To change it, you can configure [`prefetch.defaultStrategy`](/en/reference/configuration-reference/#prefetchdefaultstrategy) in your `astro.config.mjs` file:

```js title="astro.config.mjs" ins={4-6}
import { defineConfig } from 'astro/config';

export default defineConfig({
  prefetch: {
    defaultStrategy: 'viewport'
  }
});
```

### Prefetch all links by default

If you want to prefetch all links, including those without the `data-astro-prefetch` attribute, you can set [`prefetch.prefetchAll`](/en/reference/configuration-reference/#prefetchprefetchall) to `true`:

```js title="astro.config.mjs" ins={4-6}
import { defineConfig } from 'astro/config';

export default defineConfig({
  prefetch: {
    prefetchAll: true
  }
});
```

You can then opt-out of prefetching for individual links by setting `data-astro-prefetch="false"`:

```html
<a href="/about" data-astro-prefetch="false">About</a>
```

The default prefetch strategy for all links can be changed with `prefetch.defaultStrategy` as shown in the [Default prefetch strategy section](#default-prefetch-strategy).

## Prefetch programmatically

As some navigation might not always appear as `<a />` links, you can also prefetch programmatically with the `prefetch()` API from the `astro:prefetch` module:

```astro
<button id="btn">Click me</button>

<script>
  import { prefetch } from 'astro:prefetch';

  const btn = document.getElementById('btn');
  btn.addEventListener('click', () => {
    prefetch('/about');
  });
</script>
```

The `prefetch()` API includes the same [data saver mode](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/saveData) and [slow connection](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType) detection so that it only prefetches when needed.

To ignore slow connection detection, you can use the `ignoreSlowConnection` option:

```js
// Prefetch even on data saver mode or slow connection
prefetch('/about', { ignoreSlowConnection: true });
```

### `eagerness`

<p>
**Type:** `'immediate' | 'eager' | 'moderate' | 'conservative'`<br />
**Default:** `'immediate'`<br />
<Since v="5.6.0" />
</p>

With the experimental [`clientPrerender`](/en/reference/experimental-flags/client-prerender/) flag enabled, you can use the `eagerness` option on `prefetch()` to suggest to the browser how eagerly it should prefetch/prerender link targets.

This follows the same API described in the [Speculation Rules API](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/speculationrules#eagerness) and defaults to `immediate` (the most eager option). In decreasing order of eagerness, the other options are `eager`, `moderate`, and `conservative`.

The `eagerness` option allows you to balance the benefit of reduced wait times against bandwidth, memory, and CPU costs for your site visitors. Some browsers, such as Chrome, have [limits in place to guard against over-speculating](https://developer.chrome.com/blog/speculation-rules-improvements#chrome-limits)  (prerendering/prefetching too many links).

 ```astro
---
---
<script>
// Control prefetching eagerness with `experimental.clientPrerender`
import { prefetch } from 'astro:prefetch';

// This page is resource-intensive
prefetch('/data-heavy-dashboard', { eagerness: 'conservative' });

// This page is critical to the visitor's journey
prefetch('/getting-started'); // defaults to `{ eagerness: 'immediate' }`

// This page may not be visited
prefetch('/terms-of-service', { eagerness: 'moderate' });
</script>
```

To use `prefetch()` programmatically with large sets of links, you can set `eagerness: 'moderate'` to take advantage of [First In, First Out (FIFO)](https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)) strategies and browser heuristics to let the browser decide when to prerender/prefetch them and in what order:

```astro "{eagerness: 'moderate'}"
<a class="link-moderate" href="/nice-link-1">A Nice Link 1</a>
<a class="link-moderate" href="/nice-link-2">A Nice Link 2</a>
<a class="link-moderate" href="/nice-link-3">A Nice Link 3</a>
<a class="link-moderate" href="/nice-link-4">A Nice Link 4</a>
...
<a class="link-moderate" href="/nice-link-20">A Nice Link 20</a>

<script>
  import { prefetch } from 'astro:prefetch';

  const linkModerate = document.getElementsByClassName('link-moderate');
  linkModerate.forEach((link) => prefetch(link.getAttribute('href'), {eagerness: 'moderate'}));
  
</script>
```

Make sure to only import `prefetch()` in client-side scripts as it relies on browser APIs.

## Using with View Transitions

When you use [Astro’s `<ClientRouter />`](/en/guides/view-transitions/#enabling-view-transitions-spa-mode)  on a page, prefetching will also be enabled by default. It sets a default configuration of `{ prefetchAll: true }` which enables [prefetching for all links](#prefetch-all-links-by-default) on the page.

You can customize the prefetch configuration in `astro.config.mjs` to override the default. For example:
  
```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
  // Disable prefetch completely
  prefetch: false
});
```

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
  // Keep prefetch, but only prefetch for links with `data-astro-prefetch`
  prefetch: {
    prefetchAll: false
  }
});
```

## Browser support

Astro's prefetching uses [`<link rel="prefetch">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/prefetch) if supported by the browser, and falls back to the [`fetch()` API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) otherwise. 

The most common browsers support Astro's prefetching with subtle differences:

### Chrome

Chrome supports `<link rel="prefetch">`. Prefetching works as intended.

It also fully supports `<script type="speculationrules">` from the [Speculation Rules API](https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API), which can be used to further describe [prefetching strategies and rules](#eagerness), enhancing user experience for your Chrome users. You'll need to enable [`clientPrerender`](/en/reference/experimental-flags/client-prerender/) experiment to utilize this functionality with `prefetch()`

### Firefox

Firefox supports `<link rel="prefetch">` but may display errors or fail entirely:

 - Without an explicit cache header (e.g. [`Cache-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) or [`Expires`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires)), prefetching will error with `NS_BINDING_ABORTED`. 
- Even in the event of an error, if the response has a proper [`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) header, it will be re-used on navigation.
- Otherwise, if it errors with no other cache headers, the prefetch will not work.

### Safari

Safari does not support `<link rel="prefetch">` and will fall back to the `fetch()` API which requires cache headers (e.g. [`Cache-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control), [`Expires`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires), and [`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)) to be set. Otherwise, the prefetch will not work.

**Edge case:** `ETag` headers do not work in private windows.

### Recommendations

To best support all browsers, make sure your pages have the proper cache headers. 

For static or prerendered pages, the `ETag` header is often automatically set by the deployment platform and is expected to work out of the box.

For dynamic and server-side rendered pages, set the appropriate cache headers yourself based on the page content. Visit the [MDN documentation on HTTP caching](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching) for more information.

## Migrating from `@astrojs/prefetch`

The `@astrojs/prefetch` integration was deprecated in v3.5.0 and will eventually be removed entirely. Use the following instructions to migrate to Astro's built-in prefetching which replaces this integration.

<Steps>
1. Remove the `@astrojs/prefetch` integration and enable the `prefetch` config in `astro.config.mjs`:

    ```js title="astro.config.mjs" ins={6} del={2,5}
    import { defineConfig } from 'astro/config';
    import prefetch from '@astrojs/prefetch';

    export default defineConfig({
      integrations: [prefetch()],
      prefetch: true
    });
    ```

2. Convert from `@astrojs/prefetch`'s configuration options:

    - The deprecated integration used the `selector` config option to specify which links should be prefetched upon entering the viewport.
    
      Add `data-astro-prefetch="viewport"` to these individual links instead.

      ```html
      <a href="/about" data-astro-prefetch="viewport">
      ```

    - The deprecated integration used the `intentSelector` config option to specify which links should be prefetched when they were hovered over or focused.
    
      Add `data-astro-prefetch` or `data-astro-prefetch="hover"` to these individual links instead:

      ```html
      <!-- You can omit the value if `defaultStrategy` is set to `hover` (default) -->
      <a href="/about" data-astro-prefetch>

      <!-- Otherwise, you can explicitly define the prefetch strategy -->
      <a href="/about" data-astro-prefetch="hover">
      ```

    - The `throttles` option from `@astrojs/prefetch` is no longer needed as the new prefetch feature will automatically schedule and prefetch optimally.
</Steps>
